package com.wxxymakers.cklabrecruit.controller;

import com.wxxymakers.cklabrecruit.entity.RegisterInfo;
import com.wxxymakers.cklabrecruit.entity.enum_.RegStatus;
import com.wxxymakers.cklabrecruit.execption.ReApplyException;
import com.wxxymakers.cklabrecruit.service.RegisterInfoService;
import com.wxxymakers.cklabrecruit.service.SysInfoService;
import com.wxxymakers.cklabrecruit.utils.EmailUtils;
import com.wxxymakers.cklabrecruit.utils.RandomVerify;
import com.wxxymakers.cklabrecruit.utils.RestResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @AUTHOR soft
 * @DATE 2018/11/5 19:56
 * @DESCRIBE 用户报名控制器
 */
@Slf4j
@RestController
@RequestMapping("/recruit")
public class RegisterInfoController {

    private final EmailUtils emailUtils;

    private final RegisterInfoService service;

    private final SysInfoService sysInfoService;

    @Autowired
    public RegisterInfoController(RegisterInfoService service, EmailUtils emailUtils, SysInfoService sysInfoService) {
        this.service = service;
        this.emailUtils = emailUtils;
        this.sysInfoService = sysInfoService;
    }

    /**
     * 报名
     * @param verify 验证码
     * @param info 用户信息
     */
    @PostMapping("/apply")
    public RestResponse publish(@RequestParam String verify,
                                RegisterInfo info,
                                HttpServletRequest request) {
        if (!sysInfoService.canReg()) {
            return RestResponse.fail("报名已关闭！");
        }

        String code = (String) request.getSession().getAttribute(RandomVerify.S_KEY);
        if ((verify + "").equalsIgnoreCase(code)) {
            info.setStatus(RegStatus.REG);
            try {
                if (!service.isApply(info)) {
                    RegisterInfo add = service.add(info);
                    if (add != null) {
                        emailUtils.sendRegSuccess(info.getEmail(), info.getName());
                        return RestResponse.ok(add.getId());
                    }
                }
            } catch (ReApplyException e) {
                String message = e.getMessage();
                log.warn("报名失败! {}", message);
                if (e.getType() == 1) { // 学号重复 重复报名
                    return RestResponse.fail(info.getId(), message);
                }
                return RestResponse.fail(401, message); // 邮箱重复 修改邮箱重试
            }
            return RestResponse.fail("报名失败，请重试...");
        }
        return RestResponse.fail(402,"验证码错误！");
    }

    /**
     * 重新报名
     * @param verify 验证码
     * @param info 报名信息 带id
     */
    @PostMapping("/reapply")
    public RestResponse reApply(@RequestParam String verify,
                                RegisterInfo info,
                                HttpServletRequest request) {
        if (!sysInfoService.canReg()) {
            return RestResponse.fail("报名已关闭！");
        }

        String code = (String) request.getSession().getAttribute(RandomVerify.S_KEY);
        if ((verify + "").equalsIgnoreCase(code)) {
            info.setStatus(RegStatus.REG);
            if (service.change(info)) {
                emailUtils.sendRegSuccess(info.getEmail(), info.getName());
                return RestResponse.ok("重新报名成功！");
            }
            return RestResponse.fail();
        }
        return RestResponse.fail(402, "验证码错误！");
    }

    /**
     * 删除
     * @param id id
     */
    @RequiresRoles("admin")
    @PostMapping("/delete/{id}")
    public RestResponse delete(@PathVariable Integer id) {
        RegisterInfo info = service.delete(id);
        if (null != info) {
            return RestResponse.ok(info);
        }
        return RestResponse.fail("删除失败！");
    }

    /**
     * 删除
     * @param ids ids
     */
    @RequiresRoles("admin")
    @PostMapping("/deleteAll")
    public RestResponse deleteAll(@RequestParam("ids[]") Integer[] ids) {
        int num = 0;
        for (Integer id : ids) {
            RegisterInfo info = service.delete(id);
            if (null != info) {
                num++;
            }
        }
        if (num == ids.length) {
            return RestResponse.ok("全部删除成功！");
        } else if (num > 0) {
            return RestResponse.fail(201, "部分删除成功！");
        }
        return RestResponse.fail("删除失败！");
    }

    @PostMapping("/change/{id}")
    public RestResponse change(@PathVariable Integer id,
                               RegisterInfo info) {
        info.setId(id);
        if (service.change(info)) {
            return RestResponse.ok("修改成功");
        }
        return RestResponse.fail();
    }

    /**
     * 分页多条件(等于条件)查询
     * @param pageNo 页码
     * @param size   尺寸
     * @param info   相等条件
     */
    @RequiresRoles("admin")
    @PostMapping("/page/{no}")
    public RestResponse page(@PathVariable("no") Integer pageNo,
                             @RequestParam(defaultValue = "10", required = false) int size,
                             RegisterInfo info) {
        Page<RegisterInfo> page = service.getPage(pageNo, size, info);
        if (page != null) {
            return RestResponse.ok(page);
        }
        return RestResponse.fail("查询失败！");
    }

    /**
     * 根据id查询
     * @param id id
     */
    @PostMapping("/get/{id}")
    public RestResponse get(@PathVariable Integer id) {
        RegisterInfo one = service.getOne(id);
        if (null != one) {
            return RestResponse.ok(one);
        }
        return RestResponse.fail("不存在！");
    }

    /**
     * 驳回
     * @param ids 被驳回的id列表
     */
    @RequiresRoles("admin")
    @PostMapping("/reject")
    public RestResponse reject(@RequestParam("ids[]") Integer[] ids) {
        int num = 0;
        List<Integer> sids = new ArrayList<>();
        for (Integer id : ids) {
            if (service.changeStatus(id, false)) {
                num++; sids.add(id);
            }
        }
        if (num == ids.length) {
            return RestResponse.ok("驳回成功！");
        } else if (num > 0) {
            return RestResponse.fail(201, sids);
        }
        return RestResponse.fail("以是报名状态！");
    }

    /**
     * 通过
     * @param ids 被通过的id列表
     */
    @RequiresRoles("admin")
    @PostMapping("/pass")
    public RestResponse pass(@RequestParam("ids[]") Integer[] ids) {
        int num = 0;
        List<Integer> sids = new ArrayList<>();
        for (Integer id : ids) {
            if (service.changeStatus(id, true)) {
                num++; sids.add(id);
            }
        }
        if (num == ids.length) {
            return RestResponse.ok("通过成功！");
        } else if (num > 0) {
            return RestResponse.fail(201, sids);
        }
        return RestResponse.fail("已被录取！");
    }

    /**
     * 获取报名人的所有年份
     * @return 年份信息
     */
    @RequiresRoles({"admin"})
    @PostMapping("/years")
    public RestResponse years() {
        Set<String> years = service.getYears();
        if (!CollectionUtils.isEmpty(years)) {
            return RestResponse.ok(years);
        }
        return RestResponse.fail();
    }
}
